<?php

namespace App\Eloquent;

use DB;
use Ibeibeili\SinaPay\Facades\CreateActivateMember;
use Ibeibeili\SinaPay\Facades\BindingVerify;
use Ibeibeili\SinaPay\Facades\CreateBatchHostingPayTrade;
use App\Admin\Eloquent\GiftActivity;
use App\Admin\Eloquent\TradeRecords;
use App\Admin\Eloquent\Role;
use App\Admin\Eloquent\Project;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Mockery\CountValidator\Exception;
use App\Admin\Eloquent\ProjectProfit;
use QueryBankCard;
use QueryBalance;
use QueryIsSetPayPassword;
use CreateHostingTransfer;
use Log;
use App\Admin\Eloquent\Message;

class User extends Model
{

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'scope', 'username', 'email', 'password', 'identity_id','phone_number','phone_number_verified','email_verified','is_set_pay_password','bank_code'
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
    
    /**
     * 用户的Money
     * 
     * @var [array]
     */
    protected $money;

    /**
     * 获取关联的用户信息
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function userInfo()
    {
        return $this->hasOne('App\Eloquent\UserInfo');
    }

    /**
     * 当前用户的所有角色
     */
    public function roles()
    {
        return $this->belongsToMany('App\Eloquent\Role', 'role_user', 'user_id', 'role_id');
    }

    /**
     * 判断用户是否拥有指定角色
     *
     * @param  string|array $slug
     * @param  bool $requiredAll
     * @return bool
     *
     * 示例：
     *  $user->hasRole('user'); # true
     *  $user->hasRole('Agent'); # false
     *  $user->hasRole(['user', 'Agent']); # true
     *  $user->hasRole(['user', 'Agent'], true); # false
     */
    public function hasRole($slug, $requiredAll = false)
    {
        if (is_array($slug)) {
            foreach ($slug as $roleSlug) {
                $hasRole = $this->hasRole($roleSlug);

                if (!$requiredAll && $hasRole) {
                    return true;
                } elseif ($requiredAll && !$hasRole) {
                    return false;
                }
            }

            return $requiredAll;
        } else {
            foreach ($this->roles()->get() as $role) {
                if ($role->slug == $slug) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * 强制角色校验(强制404)
     * 
     * @param  [type] $slug [description]
     * @return [type]       [description]
     */
    public function checkRole($slug, $requiredAll = false){
        if(!$this->hasRole($slug, $requiredAll)){
            abort(404);
        }
    }

    /**
     * 范围查询只包括前台用户
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeFronts($query)
    {
        return $query->where('scope', 'front');
    }

    public static function paging_query(array $args, int $pagesize = 15)
    {
        $query = User::fronts()
            ->leftJoin('user_info as a', 'a.user_id', '=', 'users.id');

        //追加查询条件
        if (!empty($args['username']))
            $query = $query->where('users.username', 'like', '%' . $args['username'] . '%');

        if (!empty($args['name']))
            $query = $query->where('a.name', 'like', '%' . $args['name'] . '%');

        if (!empty($args['id_card']))
            $query = $query->where('a.id_card', 'like', '%' . $args['id_card'] . '%');

        if (!empty($args['phone']))
            $query = $query->where('a.phone', 'like', '%' . $args['phone'] . '%');

        return $query->paginate($pagesize);
    }


    /**
     * 获取保存在session中的前台用户对象
     *
     * @return mixed
     */
    public static function user()
    {
        return session(self::getFrontUserSessionKey());
    }

    /**
     * 将用户登出
     *
     * @param Request $request
     */
    public static function loginOut(Request $request)
    {
        $request->session()->remove(self::getFrontUserSessionKey());
        $request->session()->remove('prevUrl');
    }
    /**
     * 用户登陆
     *
     * @param Request $request
     * @param User $user
     */
    public static function loginIn(Request $request, User $user)
    {
        //去除密码

        // $user->__unset('password');
       $request->session()->put(self::getFrontUserSessionKey(), $user);
        // session([self::getFrontUserSessionKey()=>$user]);
        $on = new GiftActivity();
        $on->birthGift();

    }

    /**
     *
     * 用户登陆校验
     *
     * @param array $credentials
     * @return bool|null
     */
    public static function loginCheck(array $credentials)
    {
        $result = [
            'result_code' => false,
            'result_message' => '',
            'user' => null,
        ];

        $username = $credentials['username'];
        $password = $credentials['password'];

        $user = null;

        //查询用户名
        if($user = self::toUser($username)){
            //自动解锁用户
            if(date("Y-m-d H:i:s",strtotime("-1 day")) >= $user->last_login_at){
                $user->make_mistake = 0;
            }
            //查询处理用户账户状态
            if($user->make_mistake >= 5){
                    $result['result_message'] = '账号异常，请联系客服解锁';
                    return $result; 
            }

            //记录用户最后登陆时间
            $user->last_login_at = date("Y-m-d H:i:s");

            //密码校验
            if (Hash::check($password, $user->password)) {
                $user->save();
                $result['result_code'] = true;
                $result['user'] = $user;
                return $result;
            }else{
                $user->last_login_at = date('Y-m-d H:i:s');
                $user->make_mistake = $user->make_mistake + 1;
                $user->save();
                $result['result_message'] = '用户名或者密码错误';
                return $result;
            }

        }else{
                $result['result_message'] = '用户名或者密码错误';
                return $result;
        }
    }
    //根据用户名获取用户对象
    public static function toUser($username){
        //查询用户名
        $users = User::where('username', $username)
            ->orWhere('email', $username)
            ->orWhere('phone_number', $username)
            ->first();
        return $users;
    }

    /**
     * 判断用户是否登陆
     * @param Request $request
     * @return bool
     */
    public static function isLogin(Request $request)
    {
        return empty($request->session()->has(self::getFrontUserSessionKey())) ? false : true;
    }

    public static function getFrontUserSessionKey()
    {
        return config('session.front_login_user');
    }

    /**
     * 给用户发送邮件
     */
    public function sendEmailBindLink(string $email)
    {
        //生成随机验证码
        $code =rand(100000, 999999);

        //邮件内容模板
        $information = Information::where('type', 'information_email')
            ->where('position', 'email_validate_code')
            ->where('state', 1)
            ->first();
        $username = empty($this->userInfo->name) ? $this->username : $this->userInfo->name;
        //生成验证url
        $link = "http://".$_SERVER['SERVER_NAME'].'/utils/user/'.$this->id.'/emailvalidate'.'/'.md5($code);
        //替换模板内容
        $content = str_replace('{user}', $username, $information->content);
        $content = str_replace('{link}', $link, $content);

        $fa_data['content']=$content;
        $fa_data['email']=$email;
        $fa_data['title']=$information->title;
//        $email = $email;
//        $title = $information->title;

        $data['code']=$code;
        $data['email']=$email;
        if(sendEmail($fa_data)&&Cache::put(('uid_'.$this->id.'_email_validate'),$data,30)){
            return true;
        }
        return false;
    }

    /**验证邮箱
     * @param $id
     * @param $code
     */
    public function verifyEmail($id,$code){
        $r_result=true;
        try {
            DB::beginTransaction();
            $data=Cache:: pull(('uid_'.$id.'_email_validate'));
            md5($data['code'])==$code or abort('600');
            $user=User::findOrFail($id);
            $user->email=$data['email'];
            $user->save();
            $result=BindingVerify::send(['identity_id'=>$user->identity_id,'verify_type'=>'EMAIL','verify_entity'=>$data['email']]);
            $result['response_code']=='APPLY_SUCCESS' or abort('600');
            DB::commit();
        }catch(Exception $e) {
            DB::rollback();
            $r_result=false;
        }
        return $r_result;
    }
    /**
     * 获取用户绑定的银行卡
     * @return [type] [description]
     */
    public function queryBindingCard(){
        $sina_bind_card=QueryBankCard::send(['identity_id'=>$this->identity_id,'identity_type'=>'UID']);
        $bind_card=array();//array('卡信息ID','银行编号','银行卡号','户名','卡类型','卡属性')
        foreach (explode("|",$sina_bind_card['card_list']) as $item) {
            $bind_card[]=explode("^",$item);
        }
        return $bind_card;
    }
    /**
     * 查询余额
     */
    public function queryBalance(){
        $result=QueryBalance::send(['identity_id'=>$this->identity_id,'identity_type'=>'UID','account_type'=>'SAVING_POT']);
        if(!isset($result['available_balance'])){$result['available_balance']=0.00;}
        if(!isset($result['balance'])){$result['balance']=0.00;}

            $this->money['balance'] = $result['balance'];
            $this->money['available_balance'] = $result['available_balance'];
            $this->money['bonus'] = ($result['bonus'])??0;

        return $result;
    }
    /**
     * 创建并保存一个投资人用户
     * 
     * @param  array  $args [description]
     * @return [type]       [description]
     */
    public static function saveFront(array $args){

        return DB::transaction(function() use ($args){


            $user = new User($args);
            $user->scope = 'front';
            $user->password = bcrypt(md5($args['password']));
            $user->identity_id = static::createIdentityId();
            $user->save();

            $userInfo = new UserInfo($args);
            $userInfo->invite_code = static::createInviteCode();
            $userInfo->user_id = $user->id;
            $userInfo->recommended = null;
            $userInfo->org_code = config('p2pdefault.user.organizational_code');
            $userInfo->dept_code = config('p2pdefault.user.dept_code');
            $userInfo->broker_code = config('p2pdefault.user.broker_code');

            if (!empty(@$args['recommended'])) {
                if ($broker_user = UserInfo::where('invite_code', '=', $args['recommended'])->first()) {
                    if($broker_user->user->hasRole('Agent')){   //推荐人是经纪人
                        //保存经纪人code
                        $userInfo->broker_code = $broker_user->invite_code;
                        $userInfo->org_code = $broker_user->org_code;
                        $userInfo->dept_code = $broker_user->dept_code;

                        //向经纪人发送注册消息    >>>>>>>>>>>>>>>>>>>>>>>>> start

                        $u_name = '';

                        if(isset($args['phone_number']) && !empty($args['phone_number']))
                            $u_name = $args['phone_number'];

                        if(isset($args['username']) && !empty($args['username']))
                            $u_name = $args['username'];            

                        if(isset($args['email']) && !empty($args['email']))
                            $u_name = $args['email'];

                        $content_text = '<p>
    '.date('Y-m-d H:i:s').'，您的客户 ['.$u_name.'],成功注册!
</p>';
                        Message::sendMessage('sys_msg','客户注册通知 ['.$u_name.']',$content_text,$broker_user->user_id);

                        //向经纪人发送注册消息    <<<<<<<<<<<<<<<<<<<<<<<<<<< end


                    }else{
                        if(!empty($broker_user->second_broker_code) && $broker_user->second_broker_code ==$broker_user->invite_code){
                            //保存二级经纪人编码
                     
                        $userInfo->broker_code = $broker_user->broker_code;
                        $userInfo->org_code = $broker_user->org_code;
                        $userInfo->dept_code = $broker_user->dept_code;
                        $userInfo->second_broker_code = $broker_user->invite_code;
                            //向经纪人发送注册消息    >>>>>>>>>>>>>>>>>>>>>>>>> start
                            //
                        //查一级经济人
                        $broker_user1 = UserInfo::where('invite_code', $broker_user->broker_code)->first();

                        if(!$broker_user1){
                            abort(600,'一级经纪人不存在!');
                        }

                        $u_name = '';

                        if(isset($args['phone_number']) && !empty($args['phone_number']))
                            $u_name = $args['phone_number'];

                        if(isset($args['username']) && !empty($args['username']))
                            $u_name = $args['username'];            

                        if(isset($args['email']) && !empty($args['email']))
                            $u_name = $args['email'];

                        $content_text = '<p>
    '.date('Y-m-d H:i:s').'，您的客户 ['.$u_name.'] 通过二级经纪人['.$broker_user->name.'],成功注册!
</p>';
                        Message::sendMessage('sys_msg','客户注册通知 ['.$u_name.']',$content_text,$broker_user1->user_id);

                        }else{
                            //保存推荐人ID

                            $userInfo->recommended = $broker_user->user_id;
                            //发放邀请红包
                            $on = new GiftActivity();
                            $result = $on->sendGift('gift_grant_rule_5', $broker_user->user_id);
                        }
                    }
                } else {
                    abort(600,'推荐人不存在');
                }
            }

            $userInfo->save();

            if(!$role = Role::where('slug', 'User')->first()){
                abort(600, '投资人角色不存在');
            }
            //保存用户角色
            $user->roles()->attach($role->id);

            //激活sina会员
            $result = $user->createActivateMember();

            // $args['user'] = $user;

            if ($result['response_code'] != 'APPLY_SUCCESS') {
                abort(600, $result['response_message']);
            }

            return $user;
        });

    }
    /**
     * 注册二级经纪人
     * @return [type]       [description]
     */
    public static function createAgent($args){
      return DB::transaction(function() use ($args){
        $user = new User($args);
        $user->scope = 'front';
        $user->password = bcrypt(md5($args['password']));
        $user->identity_id = static::createIdentityId();
        $user->save();

        $userInfo = new UserInfo($args);
        $userInfo->invite_code = static::createInviteCode();
        $userInfo->user_id = $user->id;
        $userInfo->recommended = null;
        $userInfo->org_code = config('p2pdefault.user.organizational_code');
        $userInfo->dept_code = config('p2pdefault.user.dept_code');
        $userInfo->broker_code = config('p2pdefault.user.broker_code');

        if (!empty(@$args['second_code'])) {
          $broker_user = UserInfo::where('invite_code',$args['second_code'])->first();//一级经纪人
          if ($broker_user && $broker_user->user->hasRole('Agent')) {
            $userInfo->broker_code = $broker_user->invite_code;
            $userInfo->org_code = $broker_user->org_code;
            $userInfo->dept_code = $broker_user->dept_code;
            $userInfo->second_broker_code = $userInfo->invite_code;

            //发送站内信
            $u_name = '';
            if(isset($args['phone_number']) && !empty($args['phone_number'])){
              $u_name = $args['phone_number'];
            }
            if(isset($args['username']) && !empty($args['username'])){
              $u_name = $args['username'];            
            }
            if(isset($args['email']) && !empty($args['email'])){
              $u_name = $args['email'];
            }
            $content_text = '<p>'.date('Y-m-d H:i:s').'，您的客户 ['.$u_name.'],成功注册!</p>';
            Message::sendMessage('sys_msg','客户注册通知 ['.$u_name.']',$content_text,$broker_user->user_id);
          } else {
            abort(600,'经纪人不存在');
          }
        }

        $userInfo->save();

        if(!$role = Role::where('slug', 'User')->first()){
            abort(600, '投资人角色不存在');
        }
        //保存用户角色
        $user->roles()->attach($role->id);

        //激活sina会员
        $result = $user->createActivateMember();

        // $args['user'] = $user;

        if ($result['response_code'] != 'APPLY_SUCCESS') {
            abort(600, $result['response_message']);
        }

        return $user;
      });
    }
    /**
     * 创建用户sina会员id
     * @return [type]
     */
    protected static function createIdentityId(){
           //生成sinaUID
        do{
            $identity_id = createSinaIdentityId();

        }while(User::where('identity_id', $identity_id)->exists());

        return $identity_id;
    }

    /**
     * 创建用户推荐码
     * @return [type]
     */
    protected static function createInviteCode(){
        do{
            //为用户创建推荐码
            $invite_code = create_code(6);

        }while(UserInfo::where('invite_code', $invite_code)->exists());

        return $invite_code;
    }

    /**
     * 激活sina会员
     * @return [type]
     */
    protected function createActivateMember(){
        return CreateActivateMember::send(['identity_id' => $this->identity_id, 'identity_type' => 'UID']);
    }

    /**
     * 查询当前用户是否设置支付密码
     * 
     * @return boolean [description]
     */
    public function isSetPayPassword(){
        if($this->userInfo->is_set_pay_password == 1){
            return true;
        }else{
            //向sina发起请求,查询当前用户是否设置支付密码
            $result = QueryIsSetPayPassword::send(['identity_id' => $this->identity_id, 'identity_type' => 'UID']);
            if($result['response_code'] != 'APPLY_SUCCESS'){
                abort(600,$result['response_message']);
            }


            if($result['is_set_paypass'] == 'Y'){
                    //首次设置支付密码
                    
                    //更新用户信息表状态 >>>>>>>>>>>>>>>>>>>> start
                    
                    $this->userInfo->is_set_pay_password = 1;
                    $this->userInfo->set_pay_password_time = date('Y-m-d H:i:s');
                    $this->userInfo->save();
                    
                    //更新用户信息表状态 >>>>>>>>>>>>>>>>>>>> end

                    //调用还款的方法  TODO
                    //发送激活红包
            $on = new GiftActivity();
            $result = $on->sendGift('gift_grant_rule_7', $this->id);
            //发还款
        $this->sendPaymentMoney();
                    
                return true;
            }else{
                return false;
            }
        }
    }

    /**
     * 查询当前是否绑定银行卡
     * 
     * @return boolean [description]
     */
    public function isBindingBankCard(){
        if (empty($this->userInfo->bank_card_number))
            return false;
        else
            return true;
    }

    /**
     * 查询当前用户是否实名认证
     * 
     * @return boolean [description]
     */
    public function isSetRealName(){
        if ($this->userInfo->name_verified == 1)
            return  true;
        else
            return false;
    }

    /**
     * 查询用户是否绑定手机号码
     * 
     * @return boolean [description]
     */
    public function isBindingPhoneNumber(){
        if ($this->phone_number_verified == 1)
            return true;
        else
            return false;
    }

    /**
     * 查询用户是否绑定邮箱
     * 
     * @return boolean [description]
     */
    public function isBindingEmail(){
        if ($this->email_verified == 1)
            return true;
        else
            return false;
    }

    //TODO

    /**
     * 查询用户的累计收益
     * 
     * @return [double]
     */
    public function accumulatedIncome(){
        //TODO
        //
        $data = DB::table('project_profits')
            ->select(DB::raw('sum(profit) as profit'))
            ->where('user_id', $this->id)
            ->where('status', '<>', 0)
            ->first();
        return $data->profit??0;
    }

    /**
     * 查询用户的账户总额
     */
    public function allMoney(){
        if(!empty($this->money))
            return $this->money['balance'];
        else
            return ($this->queryBalance())['balance'];
    }

    /**
     * 查询用户的冻结总额
     * 
     * @return [type] [description]
     */
    public function frozenMoney(){
        if(!empty($this->money)){
            return $this->money['balance'] - $this->money['available_balance'];
        }
        else{
            $this->queryBalance();
            return $this->money['balance'] - $this->money['available_balance'];
        }

    }

    /**
     * 查询用户的可用总额
     * 
     * @return [type] [description]
     */
    public function availableMoney(){
        if(!empty($this->money))
            return $this->money['available_balance'];
        else
            return ($this->queryBalance())['available_balance'];
    }

    /**
     * 查询用户的存钱罐收益
     * 
     * @return [type] [description]
     */
    public function bonus(){
        $bonus;
        if(!empty($this->money))
            $bonus = $this->money['bonus'];
        else
            $bonus ($this->queryBalance())['bonus'];



        $bonus = explode('^', $bonus);

        return $bonus[count($bonus)-1];
    }

    /**ee
     * 查询用户充值的总金额
     * 
     * @return [type] [description]
     */
    public function rechargeMoney(){
        $money = (
                    DB::table('trade_records')
                    ->select(DB::raw('sum(money) as money'))
                    ->where('type',4)->where('status','SUCCESS')
                    ->where('pay_user',$this->id)
                    ->first()
                    )->money;

        return $money??0;
    }

    /**
     * 查询用户待收总金额
     * 
     * @return [type] [description]
     */
    public function collectionMoney(){
        $money = DB::table('project_profits')
                    ->select(DB::raw('sum(money) as money, sum(profit) as profit'))
                    ->where('user_id', $this->id)
                    ->where('status', 0)
                    ->first();
                    $sum = ($money->money)+($money->profit) ;
        return $sum??0;
    }

    /**
     * 查询用户的投资总金额
     * @return [type] [description]
     */
    public function investmentMoney(){
        $money =(
                    DB::table('projects_user')
                    ->select(DB::raw('sum(invest_money) as money'))
                    ->where('user_id',$this->id)
                    ->first()
                )->money;
        return $money??0;
    }

    public function basicMoney(){

        $result=QueryBalance::send(['identity_id'=>$this->identity_id,'identity_type'=>'UID','account_type'=>'BASIC']); 

        if($result['response_code'] != 'APPLY_SUCCESS'){
            return 0;
        }

        $available_balance = $result['available_balance'];

        return $available_balance?:0;
    }

    /**
     * 将用户基本户的余额转入存钱罐
     * 
     * @return [type] [description]
     */
    public function transferToSavingPot(){
        //查询用户的基本户余额

        $available_balance = $this->basicMoney();
        if($available_balance<= 0){
            return false;
        }

        

        $data = [
            'service' => 'create_hosting_transfer',
            'out_trade_no' => 'order'.microtme_format('YmdHisx'),
            'payer_identity_id' => $this->identity_id,
            'payer_identity_type' => 'UID',
            'payer_account_type' => 'BASIC',
            'payee_identity_id' => $this->identity_id,
            'payee_identity_type' => 'UID',
            'payee_account_type' => 'SAVING_POT',
            'amount' => $available_balance,
            'summary' => '由基本户自动转入存钱罐',
            'transfer_mode' => 'CASHDESK',
        ];


        $result = CreateHostingTransfer::send($data);

        // dd($result);

        // dd($result);
        return $result;
    }
    public function sendPaymentMoney(){
        $user_profit_list=ProjectProfit::where('type','=','2')
            ->where('user_id','=',$this->id)//对应的用户
            ->where('input_time','<=',date('Y-m-d H:i:s'))//应还款时间小于当前时间
            ->whereNull('pay_time')//实际还款时间为空
            ->where('status','=','0')//状态为未还款
            ->get();

        $num=$user_profit_list->count();
        $user_project_profit=$user_profit_list->groupBy('project_id')->keyBy('project_id');
        $project_ids=array();
        foreach( $user_project_profit as $project_id){
            $project_ids[]=$project_id->project_id;
        }
        $financier_id=Project::whereIn('id',$project_ids)->select('financier_id')->groupBy('id');

        if($num=0) {
            foreach ($user_profit_list as $key => $item) {
                $tread_list['tread_id'] = createSn();//订单号
                $tread_list['user_id'] = $this->identity_id;
                $tread_list['user_type'] = 'UID';//用户ID
                $tread_list['grant_type'] = 'SAVING_POT';//账户类型(存钱罐)
                $tread_list['money'] = $item->profit + $item->money;//金额
                $tread_list['list_data'] = '';//分账信息列表
                $tread_list['mark'] = '代收还款金';//摘要
                $to_tread_list[$key] = implode('~', $tread_list);

                $records=new TradeRecords([
                    'type'=>3,
                    'project_id'=>$item->project_id,
                    'sn'=>$tread_list['tread_id'],
                    'pay_user'=>$financier_id[$item->project_id]['0'],
                    'remarks'=>'还款用户',
                    'receive_user'=>$this->id,
                    'money'=>$tread_list['money'],
                    'created_at'=>date('Y-m-d H:i:s'),
                ]);
                $records->save();
            }
            $to_tread_list = implode('$', $to_tread_list);
            $data = [
                'out_pay_no' => createSn(),
                'out_trade_code' => '2002',
                'trade_list' => $to_tread_list,
                'notify_method' => 'single_notify',
                'notify_url' => 'https://' . $_SERVER['SERVER_NAME'] . '/return/payment',
            ];
            $result=CreateBatchHostingPayTrade::send($data);
            return $result;
        }
        return false;
    } 
    /**
     * 获取关联的机构用户信息
     *
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function organizationalInfo()
    {
        return $this->hasOne('App\Admin\Eloquent\OrganizationalUser');
    }
}